package com.older.wptsb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.older.wptsb.domain.dto.HealthDataDTO;
import com.older.wptsb.domain.po.Elder;
import com.older.wptsb.mapper.CommunityElderMapper;
import com.older.wptsb.service.ElderService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Random;

@Service
public class HealthDataGeneratorService {

    @Resource
    private CommunityElderMapper communityElderMapper;

    @Resource
    private ElderService elderService;

    private final Random random = new Random();

    /**
     * 每3分钟为所有老人生成一次健康数据
     * cron表达式: 秒 分 时 日 月 周
     * 0 0/3 * * * ? 表示每3分钟执行一次
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void generateHealthDataForAllElders() {
        // 获取所有老人
        List<Elder> elders = communityElderMapper.selectList(new QueryWrapper<>());

        for (Elder elder : elders) {
            // 检查是否所有必要字段都存在
            if (elder.getElderId() == null || elder.getName() == null || elder.getCommunityId() == null) {
                System.err.println("老人信息不完整，跳过生成健康数据: " + elder);
                continue;
            }

            // 为每个老人生成模拟健康数据
            HealthDataDTO healthDataDTO = generateMockHealthData(elder);

            try {
                // 直接调用服务方法而不是通过HTTP请求
                elderService.addElderHealthData(healthDataDTO);
                System.out.println("成功为老人 " + elder.getName() + " 生成健康数据: " + healthDataDTO);
            } catch (Exception e) {
                System.err.println("为老人 " + elder.getName() + " 生成健康数据时出错: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    /**
     * 为指定老人生成模拟健康数据
     * @param elder 老人信息
     * @return HealthDataDTO 模拟的健康数据
     */
    private HealthDataDTO generateMockHealthData(Elder elder) {
        HealthDataDTO healthDataDTO = new HealthDataDTO();

        // 基本信息
        healthDataDTO.setElderId(elder.getElderId());
        healthDataDTO.setElderName(elder.getName());
        try {
            healthDataDTO.setCommunityId(Integer.valueOf(elder.getCommunityId()));
        } catch (NumberFormatException e) {
            // 如果转换失败，使用默认值0
            healthDataDTO.setCommunityId(0);
            System.err.println("老人 " + elder.getName() + " 的社区ID格式不正确: " + elder.getCommunityId());
        }

        // 生成模拟健康指标
        // 心率 (正常范围: 60-100)
        healthDataDTO.setHeartRate(generateRandomValue(60, 100, 5));

        // 血氧 (正常范围: 95-100)
        healthDataDTO.setBloodOxygen(generateRandomValue(95, 100, 3));

        // 血压 (收缩压正常范围: 90-140)
        healthDataDTO.setBloodPressure(generateRandomValue(90, 140, 10));

        // 睡眠质量 (假设正常范围: 6-9小时)
        healthDataDTO.setSleepQuality(generateRandomValue(6, 9, 2));

        // 位置信息 (模拟GPS坐标)
        healthDataDTO.setLocation(generateRandomLocation());

        return healthDataDTO;
    }

    /**
     * 生成指定范围内的随机值
     * @param base 基准值
     * @param max 最大值
     * @param exceptionPercent 异常概率(百分比)
     * @return 随机值
     */
    private Integer generateRandomValue(int base, int max, int exceptionPercent) {
        // 确保max大于base
        if (max <= base) {
            max = base + 10; // 如果max不大于base，则增加10作为默认范围
        }

        // 以exceptionPercent的概率生成异常值
        if (random.nextInt(100) < exceptionPercent) {
            // 异常值，可以略高于或低于正常范围
            if (random.nextBoolean()) {
                return Math.max(0, base - random.nextInt(10) - 1); // 确保不会是负数
            } else {
                return max + random.nextInt(10) + 1;
            }
        } else {
            // 正常范围内的值
            return base + random.nextInt(max - base + 1);
        }
    }

    /**
     * 生成模拟GPS坐标
     * @return 格式为"经度,纬度"的字符串，例如"113.35991595835546,23.116611383078006"
     */
    private String generateRandomLocation() {
        // 以广州为中心的随机坐标范围
        double longitude = 113.2 + (random.nextDouble() - 0.5) * 0.2; // 经度范围约 113.1-113.3
        double latitude = 23.1 + (random.nextDouble() - 0.5) * 0.2;   // 纬度范围约 23.0-23.2

        // 保留14位小数
        return String.format("%.14f,%.14f", longitude, latitude);
    }
}
